package com.michael.leetcode;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public class IntToRoman_12 {
    private static Map<Double, String> baseMap = new HashMap<>();

    static {
        baseMap.put(1.0, "I");
        baseMap.put(5.0, "V");
        baseMap.put(10.0, "X");
        baseMap.put(50.0, "L");
        baseMap.put(100.0, "C");
        baseMap.put(500.0, "D");
        baseMap.put(1000.0, "M");
        baseMap.put(4.0, "IV");
        baseMap.put(9.0, "IX");
        baseMap.put(40.0, "XL");
        baseMap.put(90.0, "XC");
        baseMap.put(400.0, "CD");
        baseMap.put(900.0, "CM");
    }


    /*12. 整数转罗马数字
    七个不同的符号代表罗马数字，其值如下：
    符号	值
    I	1
    V	5
    X	10
    L	50
    C	100
    D	500
    M	1000
    罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规则：
    如果该值不是以 4 或 9 开头，请选择可以从输入中减去的最大值的符号，将该符号附加到结果，减去其值，然后将其余部分转换为罗马数字。
    如果该值以 4 或 9 开头，使用 减法形式，表示从以下符号中减去一个符号，例如 4 是 5 (V) 减 1 (I): IV ，9 是 10 (X) 减 1 (I)：IX。仅使用以下减法形式：4 (IV)，9 (IX)，40 (XL)，90 (XC)，400 (CD) 和 900 (CM)。
    只有 10 的次方（I, X, C, M）最多可以连续附加 3 次以代表 10 的倍数。你不能多次附加 5 (V)，50 (L) 或 500 (D)。如果需要将符号附加4次，请使用 减法形式。
    给定一个整数，将其转换为罗马数字。

    示例 1：
    输入：num = 3749
    输出： "MMMDCCXLIX"
    解释：
            3000 = MMM 由于 1000 (M) + 1000 (M) + 1000 (M)
            700 = DCC 由于 500 (D) + 100 (C) + 100 (C)
            40 = XL 由于 50 (L) 减 10 (X)
            9 = IX 由于 10 (X) 减 1 (I)
    注意：49 不是 50 (L) 减 1 (I) 因为转换是基于小数位

    示例 2：
    输入：num = 58
    输出："LVIII"
    解释：
            50 = L
            8 = VIII

    示例 3：
    输入：num = 1994
    输出："MCMXCIV"
    解释：
            1000 = M
             900 = CM
              90 = XC
               4 = IV
    提示：
            1 <= num <= 3999*/
    public String intToRoman(int num) {
        int time = 0;
        StringBuilder re = new StringBuilder();
        while (0 < num) {
            double pow = Math.pow(10, time);
            int tmp = num % 10;
            double value = tmp * pow;
            if (value > 1000) {
                double v = value / 1000;
                for (int i = 0; i < v; i++) {
                    re.insert(0, baseMap.get(1000.0));
                }
            } else {
                if (tmp == 4 || tmp == 9 || tmp == 5 || tmp == 1) {
                    re.insert(0, baseMap.get(value));
                } else if ((tmp > 5)) {
                    // 这里要拆成 5+1+1 这种形式
                    StringBuilder cc = new StringBuilder();
                    cc.append(baseMap.get(5 * pow));
                    for (int i = 1; i <= tmp - 5; i++) {
                        cc.append(baseMap.get(1 * pow));
                    }
                    re.insert(0, cc);
                } else {
                    // 这里拆成 1+1+1
                    StringBuilder cc = new StringBuilder();
                    for (int i = 1; i <= tmp; i++) {
                        cc.append(baseMap.get(1 * pow));
                    }
                    re.insert(0, cc);
                }
            }
            num = num / 10;
            time++;
        }
        return re.toString();
    }


    public String intToRoman1(int num) {
        StringBuilder re = new StringBuilder();
        if (num >= 1000) {
            for (int j = 0; j < num / 1000; j++) {
                re = re.insert(0, baseMap.get(1000.0));
            }
        }
        double tmpn = (num % 1000);
        for (int i = 2; i >= 0 ; i--) {
            double pow = (int)Math.pow(10, i);
            int tmp = (int)(tmpn / pow);
            if (tmp == 4 || tmp == 9 || tmp == 5 || tmp == 1){
                re.append(baseMap.get(tmp*pow));
            }else {
                if (tmp > 5){
                    re.append(baseMap.get(5*pow));
                    tmp = tmp-5;
                }

                for (int j = 1; j <= tmp ; j++) {
                    re.append(baseMap.get(pow));
                }
            }
            tmpn = tmpn % pow;
        }

        return re.toString();
    }


    @Test
    public void test(){
        intToRoman1(1994);
    }
}
